﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Documents;

namespace Paathshala.Kernel
{
    public enum LogType
    {
        None = 0,
        Normal = 1,
        Error = 2,
        High = 3
    }

    public class ConsoleWriter : TextWriter
    {
        private RichTextBox _output;
        private bool _alternateColor;

        public ConsoleWriter(RichTextBox output)
        {
            _output = output;
        }

        public override void WriteLine(string value)
        {
            Invoke(() => WriteLineToOutput(value));
        }

        public override void WriteLine(string value, object type)
        {
            var logType = LogType.None;
            if (type == null || Enum.TryParse(type.ToString(), out logType) == false) return;
            Invoke(() => WriteLineToOutput(value, logType));
        }

        public override void Write(string value)
        {
            Invoke(() => WriteStrToOutput(value));
        }

        public override void Write(char value)
        {
            Invoke(() => WriteCharToOutput(value));
        }

        public override Encoding Encoding
        {
            get { return System.Text.Encoding.UTF8; }
        }

        public void Clear()
        {
            _output.Document.Blocks.Clear();
        }

        private void Invoke(Action action)
        {
            if (!_output.CheckAccess())
            {
                _output.Dispatcher.BeginInvoke(action);
            }
            else
            {
                action();
            }
        }

        private void WriteLineToOutput(string value)
        {
            if (_output.Document.Blocks.Count > 1000) //Limit the size of console to 4096 lines
            {
                _output.Document.Blocks.Clear();
            }
            _alternateColor = !_alternateColor;
            _output.Document.Blocks.Add(new Paragraph() { Background = _alternateColor 
                ? Brushes.White : Brushes.Linen });
            WriteStrToOutput(value);
        }

        private void WriteLineToOutput(string value, LogType type)
        {
            if (type == null || LogType.None == type) return;
            if (_output.Document.Blocks.Count > 1000) //Limit the size of console to 4096 lines
            {
                _output.Document.Blocks.Clear();
            }
            SolidColorBrush brush = _alternateColor ? Brushes.White : Brushes.Linen;

            if (LogType.Error == type)
                brush = Brushes.Red;
            else if (LogType.High == type)
                brush = Brushes.Blue;
            _output.Document.Blocks.Add(new Paragraph() { Background = brush });
            WriteStrToOutput(value);

        }

        private void WriteStrToOutput(string str)
        {
            _output.AppendText(str);
            _output.ScrollToEnd();
        }


        private void WriteCharToOutput(char str)
        {
            _output.AppendText(str.ToString());
        }
    }
}
